package com.alone.embedded.lucene.spring;

import com.alone.embedded.lucene.constant.FieldType;
import com.alone.embedded.lucene.core.EmbeddedLucene;
import com.alone.embedded.lucene.core.EmbeddedLuceneConfig;
import com.alone.embedded.lucene.exception.EmbeddedLuceneException;
import com.alone.embedded.lucene.repository.handler.RepositoryHandler;
import com.alone.embedded.lucene.spring.annotation.ElEntity;
import com.alone.embedded.lucene.spring.util.AnnotationScanner;
import org.apache.lucene.analysis.Analyzer;
import org.springframework.beans.factory.DisposableBean;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Alone
 * @date 2022/8/26 2:18 下午
 */
public class SpringEmbeddedLucene extends EmbeddedLucene implements DisposableBean {

    public SpringEmbeddedLucene(EmbeddedLuceneConfig config) {
        super(config);
        this.start();
    }

    static EmbeddedLuceneConfig buildConfig(
            EmbeddedLuceneProperties properties,
            List<RepositoryHandler> handlers,
            FieldTypeAnalyzerMapper fieldTypeAnalyzerMapper,
            Map<String, Analyzer> analyzers
    ) {
        Map<Class<?>, ElEntity> classElEntityMap = AnnotationScanner.scanAnno(properties.getEntityPackages(), ElEntity.class);
        fieldTypeAnalyzerMapper = fieldTypeAnalyzerMapper == null ? new DefaultFieldTypeAnalyzerMapper() : fieldTypeAnalyzerMapper;
        EmbeddedLuceneConfig.Builder configBuilder = EmbeddedLuceneConfig.builder()
                .workerThreadNum(properties.getWorkerThreadNum())
                .indexPath(properties.getIndexPath())
                .repositoryHandler(handlers);

        Map<FieldType, Analyzer> fieldTypeAnalyzerMap = fieldTypeAnalyzerMapper.get();
        if (null != fieldTypeAnalyzerMap) {
            fieldTypeAnalyzerMap.forEach(configBuilder::fieldTypeAnalyzer);
        }

        for (Class<?> entity : classElEntityMap.keySet()) {
            ElEntity elEntity = classElEntityMap.get(entity);
            String docName = elEntity.value();
            if (null != docName && !docName.isEmpty()) {
                docName = entity.getName();
            }
            String analyzerBeanName = elEntity.analyzerBeanName();
            if (null != docName && !analyzerBeanName.isEmpty()) {
                try {
                    Analyzer analyzer = analyzers.get(analyzerBeanName);
                    if (Objects.nonNull(analyzer)) {
                        configBuilder.registerSource(entity, docName, analyzer);
                    } else {
                        throw EmbeddedLuceneException.of("annotation marked analyzer bean is not exist");
                    }
                } catch (Exception e) {
                    throw EmbeddedLuceneException.of(e);
                }
            } else {
                configBuilder.registerSource(entity, docName);
            }
        }
        return configBuilder.build();
    }


    @Override
    public void destroy() {
        this.close();
    }

}
